package _01_动态数组;

public class _48_旋转图像 {

    public static void main(String[] args) {
        int[][] ins = new int[][]{
                {5, 1, 9, 11},
                {2, 4, 8, 10},
                {13, 3, 6, 7},
                {15, 14, 12, 16},
        };

        _48_旋转图像 v = new _48_旋转图像();
        v.rotate(ins);

        for (int[] in : ins) {
            for (int i : in) {
                System.out.print(i + "\t");
            }
            System.out.println();
        }
    }

    // 水平旋转，加对角线旋转
    public void rotate(int[][] matrix) {
        int len = matrix.length;
        int spiltLen = len >> 1;
        // 水平翻转
        for (int i = 0; i < spiltLen; i++) {
            for (int j = 0; j < len; j++) {
                int temp = matrix[i][j];
                matrix[i][j] = matrix[len - i - 1][j];
                matrix[len - i - 1][j] = temp;
            }
        }

        // 对角线翻转
        for (int i = 0; i < len; i++) {
            for (int j = 0; j < i; j++) {
                int temp = matrix[i][j];
                matrix[i][j] = matrix[j][i];
                matrix[j][i] = temp;
            }
        }
    }

    // 辅助空间旋转法, 对于第row行第col列，旋转后直接变成第col行，第n - row - 1
    public void rotate2(int[][] matrix) {
        int len = matrix.length;
        int[][] newMatrix = new int[len][len];
        for (int i = 0; i < len; i++) {
            for (int j = 0; j < len; j++) {
                newMatrix[j][len - i - 1] = matrix[i][j];
            }
        }
        // 复制元素
        System.arraycopy(newMatrix, 0, matrix, 0, len);
    }

    // 边缘旋转法
    public void rotate1(int[][] matrix) {
        int len = matrix.length - 1;
        int count = 0;
        int n = len;
        while (n > 0) {
            int end = len - count; //
            for (int i = count; i < end; i++) {
                int row = count; // 0
                int col = i; // 0, 0
                int swapEle = matrix[row][col];
                // 行列交换
                for (int j = 0; j < 4; j++) {
                    int[] mapRowCol = mapRowCol(row, col, len, count, j);
                    int mapRow = mapRowCol[0];
                    int mapCol = mapRowCol[1];
                    int temp = matrix[mapRow][mapCol]; //
                    matrix[mapRow][mapCol] = swapEle;
                    swapEle = temp;
                    row = mapRow;
                    col = mapCol;
                }
            }
            count++;
            n -= 2;
        }
    }

    private int[] mapRowCol(int row, int col, int len, int count, int direct) {
        int[] rc = new int[2];
        if (direct == 0) {
            // 向下
            rc[0] = col;
            rc[1] = len - count;
        } else if (direct == 1) {
            // 超过向左转动
            rc[0] = len - count;
            rc[1] = len - row; //
        } else if (direct == 2) {
            rc[0] = col;
            // 超过向上转动
            rc[1] = count;
        } else {
            // 超过向右转动
            rc[0] = count;
            rc[1] = len - row;
        }
        return rc;
    }

}
